<?php
/**
 * Created by 784855684@qq.com.
 * Link: https://github.com/lichtung/wshore
 * User: linzh
 * Date: 6/25/17
 * Time: 5:43 PM
 */
declare(strict_types=1);


namespace wshore\core;


use wshore\helper\Config;

class Lang
{
    /**
     * @var string 实例代表的语言
     */
    private $lang = '';

    /**
     * @param string $lang 缺失时自动从请求中获取
     * @return Lang
     */
    public static function getInstance(string $lang = ''): Lang
    {
        static $_instances = [];
        $lang or $lang = Request::getLang();
        if (!isset($_instances[$lang])) {
            $_instances[$lang] = new self($lang);
        }
        return $_instances[$lang];
    }

    /**
     * Language constructor.
     * @param mixed|null|string $lang +
     */
    protected function __construct(string $lang)
    {
        $this->lang = $lang;
        $this->load(false);
    }


    /**
     * 语言包缓存
     * @var array
     */
    private $cache = [];

    /**
     * 获取语言包内全部映射
     * @return array
     */
    public function getAll(): array
    {
        return $this->cache;
    }

    /**
     * 获取单个值
     * @param string $key
     * @return string 返回对应语音包内的值,不存在时范返回原有的名称
     */
    public function get(string $key): string
    {
        return $this->cache[$key]??$key;
    }

    /**
     * 设置单个值
     * @param string $key
     * @param string $value
     * @return Lang
     */
    public function set(string $key, string $value): Lang
    {
        $this->cache[$key] = $value;
        return $this;
    }

    /**
     * @warn 保存配置将可能修改外部配置
     * @param bool $bothstore2outer 保存到缓存文件的同时是否保存到外部,需要注意的时，这步骤操作间造成永久的修改，所以默认是false(关闭的)
     * @return bool 返回是否保存成功，如果语言包为空，将会导致保存失败
     */
    public function store(bool $bothstore2outer = false): bool
    {
        if (!empty($this->cache)) {
            $relapath = "/i18n/{$this->lang}.php";
            $cache = (array)$this->cache;
            Config::store(WS_PATH_RUNTIME . $relapath, $cache);
            $bothstore2outer and Config::store(WS_PATH_BASE . $relapath, $cache);
            return true;
        }
        return false;
    }

    /**
     * 加载、获取语言包
     * @param bool $recache 是否刷新缓存
     * @return array
     */
    public function load(bool $recache = false): array
    {
        $relapath = "i18n/{$this->lang}.php";
        $cachefile = WS_PATH_RUNTIME . $relapath;
        # 文件不存在或者超出缓存期间
        if ($recache or !is_file($cachefile) or (WS_NOW > filemtime($cachefile) + 60)) {
            # 加载内置语言包
            $this->cache = is_file($innerpath = WS_PATH_FRAMEWORK . $relapath) ? Config::parse($innerpath, Config::TYPE_PHP) : [];
            # 加载外部语言包
            if (is_file($outerpath = WS_PATH_APP . $relapath)) {
                $outer = Config::parse($outerpath, Config::TYPE_PHP);
                $outer and $this->cache = array_merge($this->cache, $outer);
            }

            # 保存cache
            $this->store(false);


        } else {
            $this->cache = Config::parse($cachefile, Config::TYPE_PHP);
        }

        return $this->cache;
    }

    /**
     * 析构时保存语言包
     */
//    public function __destruct()
//    {
//        $this->store();
//    }
}